<?php
class pm
{
	// generates keystring and image
	function pm ($symb)
	{

		# do not change without changing font files!
		$alphabet = "0123456789abcde"; 
		
		# symbols used to draw pm
		$allowed_symbols = $alphabet;

		# string length
		$length = strlen($symb);

		# CAPTCHA image size (you do not need to change it, whis parameters is optimal)
		$width = 11 * $length;
		$height = 15;

		$foreground_color = array(43, 42, 42);
		$background_color = array(229, 234, 240);

		# JPEG quality of CAPTCHA image (bigger is better quality, but larger file size)
		$jpeg_quality = 100;
	
		$alphabet_length=strlen($alphabet);
		
		do
		{
			$this->keystring=$symb;
		
			$font_file="pm.png";
			$font=imagecreatefrompng($font_file);
			imagealphablending($font, true);
			$fontfile_width=imagesx($font);
			$fontfile_height=imagesy($font);
			$font_metrics=array();
			$symbol=0;
			$reading_symbol=false;

			// loading font
			for($i=0;$i<$fontfile_width && $symbol<$alphabet_length;$i++)
			{
				$transparent = (imagecolorat($font, $i, 0) >> 24) == 127;

				if(!$reading_symbol && !$transparent)
				{
					$font_metrics[$alphabet{$symbol}]=array('start'=>$i);
					$reading_symbol=true;
					continue;
				}

				if($reading_symbol && $transparent)
				{
					$font_metrics[$alphabet{$symbol}]['end']=$i;
					$reading_symbol=false;
					$symbol++;
					continue;
				}
			}

			$img=imagecreatetruecolor($width, $height);
			imagealphablending($img, true);
			$white=imagecolorallocate($img, 255, 255, 255);
			$black=imagecolorallocate($img, 0, 0, 0);

			imagefilledrectangle($img, 0, 0, $width-1, $height-1, $white);

			// draw text
			$x=1;
			for($i=0;$i<$length;$i++)
			{
				$m=$font_metrics[$this->keystring{$i}];
				$y=-5;				
				imagecopy($img, $font, $x, $y, $m['start'], 1, $m['end']-$m['start'], $fontfile_height);				
				$x+=$m['end']-$m['start']-2;
			}
		}
		while($x>=$width+100); // while not fit in canvas

		$img2=imagecreatetruecolor($width, $height);
		$foreground=imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
		$background=imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]);
		imagefilledrectangle($img2, 0, 0, $width, $height, $background);		
		imagefilledrectangle($img2, 0, $height, $width, $height, $foreground);
		for($x=0;$x<$width;$x++)
		{
			for($y=0;$y<$height;$y++)
			{
				$y=$y;

				if($x<0 || $y<0 || $x>=$width-1 || $y>=$height-1){
					continue;
				}else{
					$color=imagecolorat($img, $x, $y) & 0xFF;
					$color_x=imagecolorat($img, $x+1, $y) & 0xFF;
					$color_y=imagecolorat($img, $x, $y+1) & 0xFF;
					$color_xy=imagecolorat($img, $x+1, $y+1) & 0xFF;
				}

				if($color==255 && $color_x==255 && $color_y==255 && $color_xy==255)
				{
					continue;
				}
				else if($color==0 && $color_x==0 && $color_y==0 && $color_xy==0)
				{
					$newred=$foreground_color[0];
					$newgreen=$foreground_color[1];
					$newblue=$foreground_color[2];
				}
				else
				{
					$frsx=$x-floor($x);
					$frsy=$y-floor($y);
					$frsx1=1-$frsx;
					$frsy1=1-$frsy;

					$newcolor=(
						$color*$frsx1*$frsy1+
						$color_x*$frsx*$frsy1+
						$color_y*$frsx1*$frsy+
						$color_xy*$frsx*$frsy);

					if($newcolor>255) $newcolor=255;
					$newcolor=$newcolor/255;
					$newcolor0=1-$newcolor;

					$newred=$newcolor0*$foreground_color[0]+$newcolor*$background_color[0];
					$newgreen=$newcolor0*$foreground_color[1]+$newcolor*$background_color[1];
					$newblue=$newcolor0*$foreground_color[2]+$newcolor*$background_color[2];
				}
				imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newred, $newgreen, $newblue));
			}
		}
		
		header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); 
		header('Cache-Control: no-store, no-cache, must-revalidate'); 
		header('Cache-Control: post-check=0, pre-check=0', FALSE); 
		header('Pragma: no-cache');
		
		if(function_exists("imagepng"))
		{
			$myback=imagecolorclosest($img2, $background_color[0], $background_color[1], $background_color[2]);
        		imagecolortransparent($img2, $myback);
			header("Content-Type: image/x-png");
			imagepng($img2);
		}
		else if(function_exists("imagejpeg"))
		{
			header("Content-Type: image/jpeg");
			imagejpeg($img2, null, $jpeg_quality);
		}
		else if(function_exists("imagegif"))
		{
			header("Content-Type: image/gif");
			imagegif($img2);
		}
	}

	// returns keystring
	function getKeyString(){
		return $this->keystring;
	}
}

?>
